home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 287_01 / draw.c < prev    next >
Text File  |  1989-05-23  |  10KB  |  317 lines

  1. #include <stdio.h>
  2. #include <gds.h>
  3. #include <ctype.h>
  4. #include <GRADENV.h>
  5.  
  6. /*==============================================================*
  7.  *                                                              *
  8.  *    This file contains the program for Draw.                  *
  9.  *    This is a long but simple program so it does not have     *
  10.  *        a lot of comment.                                     *
  11.  *                                                              *
  12.  *==============================================================*/
  13.  
  14. #define MAXNUMMARK 10
  15.  
  16. int CURX=0, CURY=0;
  17.  
  18. struct markpt {
  19.     int x,y;
  20. } MARKER[MAXNUMMARK];   /* markers */
  21.  
  22. struct func_entry {
  23.     union {
  24.         char name[2];   /* command name */
  25.         int value;
  26.     } func;
  27.     int numparm;
  28. };
  29.  
  30. static char *str;
  31. static int rvflag = 0;  /*reverse flag */
  32.  
  33. static struct func_entry FUNTABLE[] =
  34.   { {'R','S', 0}, {'L','F', 1}, {'R','T', 1}, {'U','P', 1},
  35.     {'D','N', 1}, {'U','L', 1}, {'U','R', 1}, {'D','L', 1},
  36.     {'D','R', 1}, {'J','R', 2}, {'J','A', 2}, {'W','R', 0},
  37.     {'E','R', 0}, {'R','V', 0}, {'N','W', 0}, {'H','L', 2},
  38.     {'V','L', 2}, {'S','O', 0}, {'S','Y', 1}, {'A','S', 1},
  39.     {'M','K',-1}, {'W','N', 2}, {'D','Y', 1}, {'C','I', 1},
  40.     {'E','L', 2}, {'B','X', 4}, {'F','C', 1}, {'F','E', 2},
  41.     {'R','E', 2}, {'P','U', 0}, {'E','S', 0}, {'E','O', 1},
  42.     {'F','I', 0} };
  43.  
  44. #define NUMFUNC sizeof(FUNTABLE)/sizeof(struct func_entry)
  45. #define MAXNUMPARM 4    /* max. number of parameter for all commands */
  46.  
  47. Draw(drawstr,parm1,parm2)
  48. char *drawstr;
  49. int parm1,parm2;
  50. {
  51.     static int draw_arcspec=0xffff;
  52.  
  53.     int parm[MAXNUMPARM];
  54.     unsigned int cmd;
  55.     int move,parmcnt,chg,loop,delay,up,drawslot;
  56.     char ch;
  57.     register int chgx,chgy;
  58.  
  59.     str=drawstr;
  60.     MARKER[0].x=parm1;          /* put parm1 and parm2 into marker 0 */
  61.     MARKER[0].y=parm2;
  62.     chg=1;
  63.     if ((drawslot=EnvSave(0)) == 0) {   /* allocate a environment slot */
  64.         graderror(4,16);
  65.     }
  66.  
  67.     skipspace();        /* skip over initial spaces if any */
  68.     while (*str != NULL) {
  69.         move=1;
  70.         cmd=toupper(str[0])+((toupper(str[1])) << 8);
  71.         str+=2;
  72.         if (*str == '$') {      /* is there a DON'T MOVE indicator */
  73.             move=0;
  74.             str++;
  75.         }
  76.         skipspace();
  77.         parmcnt=0;
  78.         while(nextvalue(&parm[parmcnt++])) {    /* read parameters */
  79.             skipspace();
  80.             if (*str != ',') {
  81.                 parmcnt++;
  82.                 break;
  83.             }
  84.             str++;
  85.             skipspace();
  86.         }
  87.         parmcnt--;
  88.         for (loop=NUMFUNC-1; loop>=0; loop--) {
  89.             if (FUNTABLE[loop].func.value==cmd) break;
  90.         }
  91.         if (loop<0) {
  92.             graderror(2,17,cmd>>8,cmd&0xff);
  93.             while (*str != NULL && !isalpha(*str)) str++;
  94.             continue;
  95.         }
  96.         /* test whether correct number of parameters is supplied or not */
  97.         if ((FUNTABLE[loop].numparm!=parmcnt) && (FUNTABLE[loop].numparm>=0)) {
  98.             graderror(2,18,cmd>>8,cmd&0xff);
  99.             continue;
  100.         }
  101.         up=chgx=chgy=0;
  102.         switch (loop) { /* perform required function */
  103.         case 0: /* RS -- reset */
  104.             ResetWin();
  105.             CURX=ORGX;
  106.             CURY=ORGY;
  107.             SetOrg(0,0);
  108.             break;
  109.         case 1: /* LF -- left */
  110.             chgx = -parm[0];
  111.             goto drawline;
  112.         case 2: /* RT -- right */
  113.             chgx = parm[0];
  114.             goto drawline;
  115.         case 3: /* UP -- up */
  116.             chgy = -parm[0];
  117.             goto drawline;
  118.         case 4: /* DN -- down */
  119.             chgy = parm[0];
  120.             goto drawline;
  121.         case 5: /* UL -- up-left */
  122.             chgx = -parm[0];
  123.             chgy = -parm[0];
  124.             goto drawline;
  125.         case 6: /* UR -- up-right */
  126.             chgx = parm[0];
  127.             chgy = -parm[0];
  128.             goto drawline;
  129.         case 7: /* DL -- down-left */
  130.             chgx = -parm[0];
  131.             chgy = parm[0];
  132.             goto drawline;
  133.         case 8: /* DR -- down-right */
  134.             chgx = parm[0];
  135.             chgy = parm[0];
  136.             goto drawline;
  137.         case 9: /* JR -- jump relative */
  138.             chgx = parm[0];
  139.             chgy = parm[1];
  140. drawline:
  141.             if (chg && !up) {
  142.                 if (rvflag) Dot(CURX,CURY);
  143.                 Line(CURX,CURY,CURX+chgx,CURY+chgy);
  144.             }
  145.             if (CUR_PLOT==2) rvflag=1;
  146.             break;
  147.         case 10: /* JA -- jump absolute */
  148.             chgx = parm[0]-CURX;
  149.             chgy = parm[1]-CURY;
  150.             goto drawline;
  151.         case 11: /* WR -- write */
  152.             rvflag=chg=0;
  153.             goto settype;
  154.         case 12: /* ER -- erase */
  155.             chg=1;
  156.             rvflag=0;
  157.             goto settype;
  158.         case 13: /* RV -- reverse */
  159.             chg=2;
  160. settype:
  161.             PlotType(chg);
  162.             chg=1;
  163.             break;
  164.         case 14: /* NW -- nowrite */
  165.             chg=0;
  166.             break;
  167.         case 15: /* HL -- horizontal line */
  168.             HorzLine(CURX,CURY,parm[0],parm[1]);
  169.             chgx=parm[0];
  170.             break;
  171.         case 16: /* VL -- vertical line */
  172.             VertLine(CURX,CURY,parm[0],parm[1]);
  173.             chgy=parm[0];
  174.             break;
  175.         case 17: /* SO -- set origin */
  176.             RelOrg(CURX,CURY);
  177.             CURX=CURY=0;
  178.             break;
  179.         case 18: /* SY -- set style */
  180.             SetStyle(parm[0]);
  181.             break;
  182.         case 19: /* AS -- arc specification */
  183.             draw_arcspec=parm[0];
  184.             break;
  185.         case 20: /* MK -- mark location */
  186.             if ((parmcnt!=1) && (parmcnt!=3)) {
  187.                 graderror(2,18,cmd>>8,cmd&0xff);
  188.                 continue;
  189.             }
  190.             if ((parm[0]>=MAXNUMMARK) || (parm[0]<0)) {
  191.                 graderror(2,20,parm[0]);
  192.             }
  193.             if (parmcnt==1) {
  194.                 MARKER[parm[0]].x=CURX+ORGX;
  195.                 MARKER[parm[0]].y=CURY+ORGY;
  196.             } else {
  197.                 MARKER[parm[0]].x=parm[1]+ORGX;
  198.                 MARKER[parm[0]].x=parm[2]+ORGY;
  199.             }
  200.             break;
  201.         case 21: /* WN -- set window */
  202.             SetWin(CURX,CURY,parm[0],parm[1]);
  203.             break;
  204.         case 22: /* DY -- delay */
  205.             for (loop=parm[0]; loop>0; loop--) 
  206.                 for (delay=1000; delay>0; delay--);
  207.             break;
  208.         case 23: /* CI -- circle */
  209.             Arc1(CURX,CURY,parm[0],draw_arcspec);
  210.             break;
  211.         case 24: /* EL -- ellipse */
  212.             Earc1(CURX,CURY,parm[0],parm[1],draw_arcspec);
  213.             break;
  214.         case 25: /* BX -- box */
  215.             Box(CURX,CURY,parm[0],parm[1],parm[2],parm[3]);
  216.             break;
  217.         case 26: /* FC -- filled circle */
  218.             FillCircle(CURX,CURY,parm[0]);
  219.             break;
  220.         case 27: /* FE -- filled ellipse */
  221.             FillEllipse(CURX,CURY,parm[0],parm[1]);
  222.             break;
  223.         case 28: /* RE -- rectangle */
  224.             Rectangle(CURX,CURY,parm[0],parm[1]);
  225.             break;
  226.         case 29: /* UP pen for next command */
  227.             up=2;
  228.             break;
  229.         case 30: /* Save enviroment */
  230.             EnvSave(drawslot);
  231.             break;
  232.         case 31: /* Load environment */
  233.             EnvRsto(drawslot,KEEP_SLOT | parm[0]);
  234.             break;
  235.         case 32: /* Fill */
  236.             SolidFill(CURX,CURY);
  237.             break;
  238.         default:        /* impossible */
  239.             graderror(10,10,__FILE__,__LINE__);
  240.         }
  241.         if (up) up--;   /* still pen up ? */
  242.         if (move) {
  243.             CURX+=chgx;
  244.             CURY+=chgy;
  245.         }
  246.         ch=*str;
  247.         while ((ch != NULL) && !isalpha(ch)) ch=*(++str);
  248.     }
  249. EnvRsto(drawslot,0x7fff); /* Keep all except the slot */
  250. }
  251.  
  252. /* read next value from the draw string */
  253. static int nextvalue(result)
  254. int *result;
  255. {
  256.     char ch,ch2,ch3;
  257.     int temp,negative;
  258.  
  259.     ch = *str;
  260.     if ((ch=='%')